/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package generateCLP;

import genetic.Chromosome;
import genetic.Individual;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Vector;
import reader.Filereader;
import reader.Header;

/**
 *
 * @author Danzz
 */
public class CLPWriter {
    StringBuilder clpFile;

    class DefFunctions{} // not implemented
    
    class Clause {
        StringBuilder content;
        public Clause(){content=new StringBuilder();}
        public void putFacts(String fact){content.append('(').append(fact).append(')');}
        public void putNotFacts(String notfact) {content.append("(not (").append(notfact).append("))");}
        public Boolean isEmpty(){return content.length()==0;}
        @Override
        public String toString(){return content.toString();}
    }
    
    class DefRule {
        String name;
        ArrayList<Clause> LHS;
        ArrayList<Clause> RHS;
        public DefRule(String name){this.name=name;LHS = new ArrayList<Clause>();RHS = new ArrayList<Clause>();}
        public void addLHS(Clause c){LHS.add(c);}
        public void addRHS(Clause d){RHS.add(d);}
        String concactList(ArrayList<Clause> lc) {StringBuilder sb = new StringBuilder();for(Clause c : lc) {sb.append(c);} return sb.toString();}
        @Override
        public String toString(){StringBuilder sb = new StringBuilder(); sb.append("(defrule ").append(name).append("\n\t\t").append(concactList(LHS)).append("\n\t\t").append("=>").append("\n\t\t").append(concactList(RHS)).append("\n)\n\n");return sb.toString();}
    }
    
    class DefFacts{
        String name;
        String description;
        ArrayList<Clause> facts;
        public DefFacts(String name, String description){this.name=name;this.description=description;facts=new ArrayList<Clause>();}
        public void addFact(Clause c){facts.add(c);}
        String concactList(ArrayList<Clause> lc) {StringBuilder sb = new StringBuilder();for(Clause c : lc) {sb.append(c);} return sb.toString();}
        @Override
        public String toString(){StringBuilder sb = new StringBuilder();sb.append("(deffacts ").append(name).append(" \"").append(description).append("\" ").append(concactList(facts)).append(")"); return sb.toString();}
    }
    
    public CLPWriter() {
        clpFile = new StringBuilder();
    }
    
    public void constructRule(ArrayList<Chromosome> listChromosome, Header header) {
        int ruleKe = 0;
        for (Chromosome cs : listChromosome) {
            ArrayList<String> al = header.constructValueFromBitString(cs.getContent());
            DefRule dr = new DefRule("Rule-"+(ruleKe+1));
            int idxAttrib = 0;
            Clause c= new Clause();
            Clause d= new Clause();
            for (String s : al) {
                if (idxAttrib!=header.idxClass && !s.isEmpty()) {
                    c.putFacts(header.attribString.get(idxAttrib) +" "+s);
                } else if (idxAttrib==header.idxClass && !s.isEmpty()) {
                    // class
                    d.putFacts("printout t \""+header.getDataTypeFromIdx(idxAttrib).deskripsiPertanyaan + " " + s +"\" crlf");
                }
                idxAttrib++;
            }
            if (cs.getNCovered()!=0 && !c.isEmpty() && !d.isEmpty()) {
                Clause e = new Clause();
                // tambah clause not solution found
                e.putNotFacts("solution found");
                dr.addLHS(e);
                dr.addLHS(c);
                Clause f = new Clause();
                // tambah assert fakta solution found
                f.putFacts("solution found");
                Clause g = new Clause();
                g.putFacts("assert "+f.toString());
                dr.addRHS(g);
                dr.addRHS(d);
                clpFile.append(dr);
            }
            
            ruleKe++;
        }
        // tambah solution default
        DefRule dr = new DefRule("Rule-Default");
        Clause c= new Clause();
        c.putNotFacts("solution found");
        Clause d= new Clause();
        d.putFacts("printout t \"Solusi tidak bisa ditemukan.\" crlf");
        dr.addLHS(c);
        dr.addRHS(d);
        clpFile.append(dr);
    }
    
    public void doWrite(String filename) {
        try {
            if (clpFile.length()==0)
                throw new Exception("Rule kosong");
            // Create file 
            FileWriter fstream = new FileWriter(filename);
            BufferedWriter out = new BufferedWriter(fstream);
            out.write(clpFile.toString());
            //Close the output stream
            out.close();
        } catch (Exception e) {//Catch exception if any
            System.err.println("Error: " + e.getMessage());
        }
    }
    
    
    public String buildDefFacts(Header header, ArrayList<String> jawaban) {
        ArrayList<String> attrib = header.attribString;
        DefFacts df = new DefFacts("Fakta-1", "Jawaban dari user");
        int idx = 0;
        for (String jawab : jawaban) {
            Clause c = new Clause();
            c.putFacts(attrib.get(idx)+" "+jawab);
            if (header.getDataTypeFromIdx(idx).typeNominal.contains(jawab))
                df.addFact(c);
            idx++;
        }
        return df.toString();
    }
    
   
    public static void main(String[] args) {
        Filereader fr = new Filereader("dataset\\nursery.arff");
        fr.doRead();
        Individual id = new Individual(46,fr.getHeader());
        System.out.println("Jumlah attribut "+fr.getHeader().getNumAttribute());
        System.out.println("indeks kelas "+fr.getHeader().idxClass);
        CLPWriter w = new CLPWriter();
        w.constructRule(id.getArrayChromosome(), fr.getHeader());
        w.doWrite("rule_generate.clp");
    }
    
}
